home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / devel / lang / ada / adaed-1.11 / adaed-1 / Adaed-1.11.0a / recover.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-02-07  |  18.1 KB  |  755 lines

  1. /*
  2.  * Copyright (C) 1985-1992  New York University
  3.  * 
  4.  * This file is part of the Ada/Ed-C system.  See the Ada/Ed README file for
  5.  * warranty (none) and distribution info and also the GNU General Public
  6.  * License for more details.
  7.  
  8.  */
  9.  
  10. #include "ada.h"
  11. #include "miscprots.h"
  12. #include "prsutilprots.h"
  13. #include "followprots.h"
  14. #include "actionprots.h"
  15. #include "lookupprots.h"
  16. #include "pspansprots.h"
  17. #include "adalexprots.h"
  18. #include "errsprots.h"
  19. #include "recoverprots.h"
  20.  
  21. /*    Variables needed for scope and secondary recoveries */
  22.  
  23. extern int *open_seq;
  24. /* struct two_pool *closer_toksyms;
  25.  struct two_pool *closer_bottom; */
  26. extern int n_open_seq;
  27. extern int n_closer_toksyms;
  28. extern int nps;
  29.  
  30. extern struct two_pool *closer_toksyms;
  31. extern char *CLOSER_MESSAGE_SYMS();
  32. extern char closer_candidates[13][3][5];
  33.  
  34. #define EQ(s, t) (strcmp(s, t) == 0)
  35.  
  36. char *err_message(int k, struct prsstack *curtok)        /*;err_message*/
  37. {
  38.     /*    Form error message for secondary recovery
  39.      *  The parameter 'k' indicates the point in the parse and state stacks
  40.      *  at which the recovery is being made
  41.      */
  42.  
  43.     char *e_m_s,
  44.     *err_mess;
  45.     /* k is index into state stack (not parse stack because it is off by 1) */
  46.     int pp = stack_size(sta_stack) - k;
  47.     struct prsstack *prs_stack_k = prs_stack;
  48.  
  49.     if (k == 1)
  50.         /* this is case where there is 1 element on the state stack and 
  51.           * the parse stack is empty (i.e. all input is rejected)
  52.           */
  53.         return ("Unexpected input");
  54.  
  55.     while (--pp >= 0)
  56.         prs_stack_k = prs_stack_k-> prev;
  57.  
  58.     if (EQ((err_mess = err_msg_syms(prs_stack_k->symbol)) , "")) {
  59.         int act;
  60.         struct two_pool *sta_stack_k = sta_stack;
  61.         int kk = stack_size(sta_stack) - k;
  62.  
  63.         while (--kk >= 0)
  64.             sta_stack_k = sta_stack_k -> link;
  65.  
  66.         act = action((int)(sta_stack_k->val.state), curtok->symbol);
  67.  
  68.         if (act > NUM_STATES) {
  69.             e_m_s = err_msg_syms(lhs[act - NUM_STATES - 1]);
  70.             return(EQ(e_m_s , "") ? "Unexpected input" : e_m_s);
  71.         }
  72.         else
  73.             return ("Unexpected input");
  74.  
  75.     }
  76.     else
  77.         return (err_mess);
  78. }
  79.  
  80.  
  81. int prs_block(struct two_pool *states, struct two_pool *toks)    /*;prs_block*/
  82. {
  83.     /* This parse checker returns true if the parse blocks and false  if
  84.      * it  does  not  or  if it cannot be determined that it will block.
  85.      * The sequence of states need not be complete, so  it    is  possible
  86.      * for    a  reduction  to use up all the states.     This makes the goto
  87.      * undetermined.  In such a case the FOLLOW set for  the  left    hand
  88.      * side     is  used.  If the next token is not in the follow set, then
  89.      * surely the parse must block eventually, but if it is not, we have
  90.      * to conclude that not blocking is possible.  The value returned is
  91.      * the predicate 'the parse must block if the state  stack  contains
  92.      * states as a suffix and the token sequence contains toks as a pre-
  93.      * fix'.
  94.      */
  95.     int act, red, nolh, n;
  96.     int ts;
  97.     struct two_pool *top_tp;
  98.     struct two_pool *tmp_tp;
  99.     int    cs;
  100.     short    n_states = 1;
  101.  
  102.     ts = toks->val.state;        /* ts frome toks */
  103.     toks = toks->link;
  104.  
  105.     cs = states->val.state;    /* cs = top(states) */
  106.  
  107.     while(1) {    /* while true */
  108.  
  109.         act = action(cs, ts);
  110.  
  111.         if (act == 0)
  112.             return 1;                            /* parse error */
  113.         else if (act < NUM_STATES) {        /* shift action */
  114.             if (toks == (struct two_pool *)0)
  115.                 return 0;
  116.  
  117.             /* tmp_tp = toks; destroys prs_toks!! */    /* for re-use */
  118.             ts = toks->val.state;        /* next token */
  119.             toks = toks->link;
  120.  
  121.             tmp_tp = TALLOC();
  122.             tmp_tp->link = states;
  123.             tmp_tp->val.state = (cs = act);    /* update stateseq */
  124.             states = tmp_tp;
  125.             n_states ++;
  126.         }
  127.         else if ((red = (act - NUM_STATES )) == 0)    /* accept action */
  128.             return 0;
  129.         else {    /* reduce action */
  130.             int nn;
  131.             red --;        /* Adjust for 0 offset arrays */
  132.             nolh = lhs[red];
  133.             n = n_states - rhslen[red] + 1;
  134.             nn = rhslen[red];
  135.             if (n <= 1)
  136.                 return (is_terminal(ts) && !in_FOLLOW(nolh, ts) );
  137.             /* replace rhs states with lhs    
  138.              * states[n] = (cs = action(states(n - 1), nolh));    
  139.              */
  140.  
  141.             if (nn == 0) {
  142.                 tmp_tp = TALLOC();
  143.                 tmp_tp->link = states;
  144.                 states = tmp_tp;
  145.             }
  146.             else if (nn > 1 ) {
  147.                 top_tp = states;
  148.                 while (--nn > 1)
  149.                     states = states->link;
  150.                 tmp_tp = states;
  151.                 states = states->link;
  152.                 TFREE(top_tp, tmp_tp);
  153.             }
  154.             states->val.state = 
  155.               (cs = action((int)(states->link->val.state), nolh));
  156.             /* n_states -= nn; */
  157.             n_states -= rhslen[red] - 1;
  158.         }
  159.     }
  160. }
  161.  
  162. int prs_check(struct two_pool *stateseq, int *tokseq, int n_tokseq)
  163.                                                             /*;prs_check*/
  164. {
  165.     int ts;
  166.     int cs;
  167.     struct two_pool *top_tp;
  168.     struct two_pool *tmp_tp;
  169.     struct two_pool *temp_stateseq;
  170.     int n_temp_stateseq;
  171.     int nsh;
  172.     int red, act;
  173.  
  174.     /* This is just a parser that operates from the token sequence, tokseq.
  175.      * It returns when an error occurrs, an accept occurs, or the sequence
  176.      * of tokens is exhausted.
  177.      */
  178.  
  179.     /* n_tokseq is actually the size of tokseq - 1. It is used as an offset 
  180.      * into tokseq (which starts at zero). However, when the size of tokseq
  181.      * is desired, we use (n_tokseq + 1) 
  182.      */
  183.  
  184.     copystack(stateseq, &temp_stateseq, &n_temp_stateseq);
  185.  
  186.     nsh = 0;                /* Number of tokens shifted */
  187.  
  188.     ts = tokseq[n_tokseq];            /* Top of tokseq    */
  189.     cs = temp_stateseq->val.state;        /* Top of stateseq    */
  190.  
  191.     while(1)    /* while true */
  192.     {
  193.         act = action(cs, ts);
  194.  
  195.         if (act == 0)
  196.             return nsh;            /* parse error */
  197.         else if (act < NUM_STATES)    /* Shift action */
  198.         {
  199.             if ( (++nsh ) >= (n_tokseq + 1))    /*  up shift count */
  200.                 return nsh;    /*  gone far enough */
  201.  
  202.             ts = tokseq[n_tokseq - nsh];    /* next token */
  203.  
  204.             tmp_tp = TALLOC();    /* Update stateseq */
  205.             tmp_tp->val.state = ( cs = act);
  206.             tmp_tp->link = temp_stateseq;
  207.             temp_stateseq = tmp_tp;
  208.         }
  209.         else if ((red = (act - NUM_STATES )) == 0  ) /* accept action */
  210.             return    ((ts == EOFT_SYM) ? (n_tokseq + 1) : nsh);
  211.         else {                    /* reduce action */
  212.             int nn;
  213.             red --;        /* adjust for 0 offset arrays */
  214.             nn = rhslen[red];
  215.  
  216.             /*     replace rhs states with lhs
  217.              *
  218.              *    stateseq(nn..) := [cs := ACTION(stateseq(nn-1), nolh)];        
  219.              *
  220.              *  Since the top element will be replaced, we strip off nn - 1
  221.              *  elements and then replace the top one.
  222.              *  There are 3 cases : 
  223.              *    nn == 0 :    allocate a new top element
  224.              *            for the state stack
  225.              *    nn == 1 :    Leave the top element for
  226.              *            replacement
  227.              *    nn >  1 :    Strip nn - 1 off the stack.
  228.              *            leaving the top element for
  229.              *            replacement
  230.              */
  231.  
  232.             if ( nn == 0 ) {
  233.                 tmp_tp = TALLOC();
  234.                 tmp_tp->link = temp_stateseq;
  235.                 temp_stateseq =     tmp_tp;
  236.             }
  237.             else if (nn > 1) {
  238.                 top_tp = temp_stateseq;
  239.                 while (--nn > 1)
  240.                     temp_stateseq = temp_stateseq->link;
  241.                 tmp_tp = temp_stateseq;
  242.                 temp_stateseq = temp_stateseq->link;
  243.                 TFREE(top_tp, tmp_tp);
  244.             }
  245.  
  246.             /* Replace the top element with the GOTO    */
  247.  
  248.             temp_stateseq->val.state = 
  249.               (cs = action((int)(temp_stateseq->link->val.state), lhs[red]));
  250.         }
  251.     }
  252. }
  253.  
  254. int scope_recovery(int k, int index, int *open_seq)        /*;scope_recovery*/
  255. {
  256.     int exists = 0;
  257.     int open_loc;
  258.     struct prsstack *prstmp;
  259.     int opener;
  260.     struct two_pool *tmp_tp, *saved_tail, *closer_head, *closer_tail;
  261.     struct two_pool *STA_STACK;
  262.     int closer;
  263.     int i, closer_index;
  264.     int kk = k;
  265.     int ind;
  266.     int *tmp_toksyms;
  267.     int n_tmp_toksyms;
  268.     int prs_distance;
  269.     int check_dist;
  270.     int n_closer;
  271.  
  272.     /* The parameter 'k' indicates the portion of the state stack with
  273.      * which the parse check is to be performed. The parameter 
  274.      * 'index' indicates the portion of the parse stack to be used when
  275.      * looking for the next opener to be closed.
  276.      */
  277.  
  278.     /*
  279.      * if not exists ind in [index .. n_open_seq] 
  280.      *                | k >= open_seq(ind) then
  281.      *                        return false;
  282.      * end if;
  283.      *
  284.      *        Assume that no such ind exists. Loop through, looking for
  285.      *        one.
  286.      */
  287. #ifdef EDEBUG
  288.     if (trcopt)
  289.         fprintf(errfile, "AT PROC: scope_recovery(%d, %d, %d)\n", k, index,
  290.           *open_seq);
  291. #endif
  292.  
  293.     for ( ind = index; ind < n_open_seq; ind++ )
  294.         if ( k - 1 >= open_seq[ind]) {
  295.             /* adjust to k-1 because in C version (only), size of
  296.              * parse stack is 1 less than size of state stack
  297.              */
  298.             exists = 1;
  299.             break;
  300.         }
  301.  
  302.     if (!exists)
  303.         return 0;
  304.  
  305.     open_loc = nps - open_seq[ind];
  306.  
  307.  
  308.     for (prstmp = prs_stack; open_loc--; prstmp = prstmp->prev);
  309.     opener = prstmp->symbol;
  310.     /* Keep prstmp for the error message */
  311.  
  312.  
  313.     /* Map opener into an array index */
  314.     opener = open_index(opener);
  315.     /*
  316.      *    closer_candidates := 
  317.      *            { CLOSER_SYMS(j) :
  318.      *                    j in CLOSER_MAP_SYMS(opener)};
  319.      */
  320.  
  321.     /*    (for closer in closer_candidates) */
  322.  
  323.     for (closer = 0    ; closer_candidates[opener][closer][0] != 0; closer++ )
  324.     {
  325. #ifdef EDEBUG
  326.         if (trcopt)
  327.             fprintf(errfile, "opener %d  closer %d  cand: %c\n", opener, closer,
  328.               closer_candidates[opener][closer][0]);
  329. #endif
  330.         /*    
  331.          *   closer_toksyms := closer + closer_toksyms; 
  332.          *
  333.          *    These are then appended onto the end of TOKSYMS.
  334.          *    This will be represented as a linked list of values.
  335.          */
  336.  
  337.         /* First set up the list for closer */
  338.         closer_head = closer_tail = TALLOC();
  339.         closer_head->link = (struct two_pool *)0;
  340.         closer_head->val.state = closer_candidates[opener][closer][0];
  341.         for(i = 1, n_closer = 1; 
  342.           ((closer_candidates[opener][closer][i] != 0) && (i <= 4)); 
  343.           n_closer++, i ++ ) {
  344.             tmp_tp = TALLOC();
  345.             tmp_tp->link = (struct two_pool *)0;
  346.             tmp_tp->val.state = closer_candidates[opener][closer][i];
  347.             closer_tail->link = tmp_tp;
  348.             closer_tail = tmp_tp;
  349.         }
  350.  
  351.         saved_tail = closer_tail;
  352.         closer_tail->link = closer_toksyms;
  353.         closer_toksyms = closer_head;
  354.         n_closer_toksyms += n_closer;
  355.  
  356.         /*    Set tmp_toksyms = TOKSYMS + closer_toksyms */
  357.  
  358.         tmp_toksyms = (int *)emalloc((1 + n_TOKSYMS + n_closer_toksyms)
  359.             * sizeof(int) );
  360.         for (i = 0; i <= n_TOKSYMS; i++)
  361.             tmp_toksyms[i] = TOKSYMS[i];
  362.         n_tmp_toksyms = n_TOKSYMS;
  363.         for (tmp_tp = closer_toksyms; tmp_tp != (struct two_pool *)0;
  364.           tmp_tp=tmp_tp->link )
  365.             tmp_toksyms[++n_tmp_toksyms] = tmp_tp->val.state;
  366.  
  367.  
  368.  
  369.         /* Take the top n_sta_stack - k elements off the state stack, 
  370.          * keeping them so as to be able to restore the stack after the call.
  371.          */
  372.  
  373.         STA_STACK = sta_stack;
  374.  
  375.         kk = (n_sta_stack = stack_size(STA_STACK)) - k;
  376.         while(--kk > 0)
  377.             STA_STACK = STA_STACK->link;
  378.  
  379.         /* prs_distance = 
  380.          *    prs_check(STA_STACK(1 .. k), TOKSYMS + closer_toksyms);
  381.          */
  382.  
  383.         prs_distance = prs_check(STA_STACK, tmp_toksyms, n_tmp_toksyms);
  384.  
  385.         check_dist = n_closer_toksyms;
  386.  
  387.         if ((prs_distance >= (check_dist + MIN_LEN + 1 + BACKUPTOKS))
  388.           || ((prs_distance >= check_dist)
  389.           && (scope_recovery(k, ind + 1, open_seq))) ) {
  390.             struct tok_loc location;
  391.             char    msg[200];
  392.  
  393.             /* opl := PRS_STACK(open_loc);
  394.              * opl := l_span(opl);
  395.              * opl := top(opl);
  396.              */
  397. #ifdef DEBUG
  398.             if (trcopt)
  399.                 fprintf(errfile, "Successful scope recovery\n");
  400. #endif
  401.             location = l_span(prstmp);
  402.             /* CLOSER_MESSAGE_SYMS is indexed by the sum of the values in
  403.              * each closer, where closer is an element of 
  404.              * closer_candidates[opener]. 
  405.              * I.e.     +/closer_candidates[opener][closer]
  406.              */
  407.  
  408.  
  409.             for (i = 0 , closer_index = 0;
  410.               ((i <= 4) && (closer_candidates[opener][closer][i] != 0)); i++)
  411.                 closer_index += closer_candidates[opener][closer][i];
  412.  
  413.             /* ERR_MSGS := [ CLOSER_MESSAGE_SYMS(closer) 
  414.              *   + ' on line ' + str (opl(1)) ] + ERR_MSGS;
  415.              */
  416.             sprintf(msg, "%s on line %d",
  417.               CLOSER_MESSAGE_SYMS(closer_index), location.line );
  418.             syntax_err( LLOC(curtok), RLOC(curtok), msg);
  419.  
  420.             return 1;
  421.         }
  422.         else {
  423.             /*    closer_toksyms(1 .. n_closer) := []; 
  424.              *
  425.              *    Since we saved the head and tail pointers of the list closer,
  426.              *  this can be done by setting closer_toksyms to point to the 
  427.              *  tail's link.
  428.              */
  429.  
  430.             closer_toksyms = saved_tail->link;
  431.             n_closer_toksyms -= n_closer;
  432.         }
  433.     }
  434.  
  435. #ifdef EDEBUG
  436.     if (trcopt)
  437.         fprintf(errfile, "recursive call #2\n");
  438. #endif
  439.     return scope_recovery(k, ind + 1, open_seq);
  440.  
  441. }
  442.  
  443.  
  444. int stack_size(struct two_pool *s)                            /*;stack_size*/
  445. {
  446.     int size = 0;
  447.     struct two_pool *tmp_tp = s;
  448.  
  449.     while (tmp_tp != (struct two_pool *)0) {
  450.         tmp_tp = tmp_tp->link;
  451.         size ++;
  452.     }
  453.     return (size);
  454. }
  455.  
  456. int spell(char *s, char *t)                                        /*;spell*/
  457. {
  458.     /*    spell : return distance between two names    */
  459.     /*  See Kernighan & Pike */
  460.     /*
  461.      *  very rough spelling metric :
  462.      *    0 if strings are identical
  463.      *    1 if two chars are transposed
  464.      *    2 if one char wrong, added or deleted
  465.      *    3 otherwise
  466.      */
  467.     while (*s++ == *t)
  468.         if (*t++ == '\0')
  469.             return 0;        /* exact match */
  470.     if (*--s)    {
  471.         if (*t)        {
  472.             if (s[1] && t[1] && *s == t[1]
  473.               && *t == s[1] && EQ(s + 2, t + 2))
  474.                 return 1;    /* transposition */
  475.             if (EQ(s + 1, t + 1))
  476.                 return 2;    /* 1 char mismatch */
  477.         }
  478.         if (EQ(s + 1, t))
  479.             return 2;  /* extra character */
  480.     }
  481.     if(*t && EQ(s, t + 1))
  482.         return 2;    /* missing character */
  483.     return 3;
  484. }
  485.  
  486. #undef EQ
  487.  
  488. void try_deletion()                                            /*;try_deletion*/
  489. {
  490.     int    u;
  491.     int ct;
  492.     struct cand    *candidate;
  493.  
  494. #ifdef DEBUG
  495.     if (trcopt)
  496.         fprintf(errfile, "Try_deletion called\n");
  497. #endif
  498.  
  499.     if (TOKSYMS[n_TOKSYMS] >= EOFT_SYM) /* do not delete a nonterminal */
  500.         return;
  501.  
  502.     ct = TOKSYMS[n_TOKSYMS--];
  503.  
  504.     u = prs_check(sta_stack, TOKSYMS, n_TOKSYMS) - BACKUPTOKS;
  505. #ifdef DEBUG
  506.     if (trcopt)
  507.         fprintf(errfile, "prs_check returned %d\n", u);
  508. #endif
  509.  
  510.     if (u > MAX_CHECK ) {
  511.         candidate = CANDALLOC();
  512.         candidate->token_sym = ct;
  513.         candidate->backup_toks = BACKUPTOKS;
  514.         candidate->next = (struct cand *)0;
  515.         MAX_CHECK = u;
  516.         cand_clear();
  517.         CANDIDATES[DELETE] = candidate;
  518.         n_CANDIDATES[DELETE] = 1;
  519. #ifdef DEBUG
  520.         if (trcopt)
  521.             fprintf(errfile, "[ %s %d ] ", TOKSTR(ct), u);
  522. #endif
  523.     }
  524.     else if (u == MAX_CHECK ) {
  525.         candidate = CANDALLOC();
  526.         candidate->token_sym = ct;
  527.         candidate->backup_toks = BACKUPTOKS;
  528.         candidate->next = CANDIDATES[DELETE];
  529.         CANDIDATES[DELETE] = candidate;
  530.         n_CANDIDATES[DELETE] ++;
  531. #ifdef DEBUG
  532.         if (trcopt)
  533.             fprintf(errfile, "[ %s %d ] ", TOKSTR(ct), u);
  534. #endif
  535.     }
  536.  
  537. #ifdef DEBUG
  538.     if (trcopt)
  539.         fprintf(errfile, "\n");
  540. #endif
  541.     TOKSYMS[++n_TOKSYMS] =    ct;
  542.  
  543. }
  544.  
  545. void try_insertion()                                    /*;try_insertion*/
  546. {
  547.     int        u;
  548.     short    ct;
  549.     struct cand * candidate;
  550.     struct two_pool *tmp_tp;
  551.  
  552. #ifdef DEBUG
  553.     if (trcopt) {
  554.         fprintf(errfile, "Try Insertion called\n");
  555.         fprintf(errfile, "MAX_CHECK = %d\n", MAX_CHECK);
  556.     }
  557. #endif
  558.     ct = TOKSYMS[n_TOKSYMS];
  559.  
  560.     TOKSYMS[++n_TOKSYMS] = 0;
  561.  
  562.  
  563.     /* (for t in POSS_TOK) */
  564. #ifdef DEBUG
  565.     if (trcopt)
  566.         fprintf(errfile, "Possible inserts : ");
  567. #endif
  568.     tmp_tp = POSS_TOK;
  569.     while(tmp_tp != (struct two_pool *)0) {
  570.         TOKSYMS[n_TOKSYMS] = tmp_tp->val.state;
  571.  
  572.         u = prs_check(sta_stack, TOKSYMS, n_TOKSYMS) - (BACKUPTOKS + 2);
  573.  
  574. #ifdef DEBUG
  575.         if (trcopt)
  576.             fprintf(errfile, " [ %s,%d,%d ] ",
  577.               namelist((int)(tmp_tp->val.state)), u, BACKUPTOKS);
  578. #endif
  579.  
  580.         if (u > MAX_CHECK) {
  581.             MAX_CHECK = u;
  582.             candidate = CANDALLOC();
  583.             candidate->token_sym = tmp_tp->val.state;
  584.             candidate->t3 = ct;
  585.             candidate->backup_toks = BACKUPTOKS;
  586.             candidate->next = (struct cand *)0;
  587.             cand_clear();
  588.             CANDIDATES[INSERT] = candidate;
  589.             n_CANDIDATES[INSERT] = 1;
  590.         }
  591.         else if (u == MAX_CHECK) {
  592.             candidate = CANDALLOC();
  593.             candidate->token_sym = tmp_tp->val.state;
  594.             candidate->t3 = ct;
  595.             candidate->backup_toks = BACKUPTOKS;
  596.             candidate->next = CANDIDATES[INSERT];
  597.             CANDIDATES[INSERT] = candidate;
  598.             n_CANDIDATES [INSERT] ++;
  599.         }
  600.  
  601.         tmp_tp = tmp_tp->link;
  602.     }
  603. #ifdef DEBUG
  604.     if (trcopt)
  605.         fprintf(errfile, "\n");
  606. #endif
  607.  
  608.     n_TOKSYMS--;
  609. #ifdef DEBUG
  610.     if (trcopt)
  611.         fprintf(errfile, "At end, MAX_CHECK = %d\n", MAX_CHECK);
  612. #endif
  613.  
  614. }
  615.  
  616. void try_merge(struct prsstack *tok1, struct prsstack *tok2)    /*;try_merge*/
  617. {
  618.     int    ct, nt;
  619.     int j, u;
  620.     int    new_tok_sym;
  621.     char  *tok1v;
  622.     char  *tok2v;
  623.     char  *newtok;
  624.     struct cand *candidate;
  625.  
  626. #ifdef DEBUG
  627.     if (trcopt)
  628.         fprintf(errfile, "Try_merge called\n");
  629. #endif
  630.  
  631.     ct = TOKSYMS[n_TOKSYMS--];
  632.     nt = TOKSYMS[n_TOKSYMS--];
  633.  
  634.     tok1v = find_name(tok1);
  635.     tok2v = find_name(tok2);
  636.  
  637.     /* Allocate space for the newtok */
  638.     newtok = malloc((unsigned)(strlen(tok1v) + strlen(tok2v) + 2));
  639.     strcpy(newtok, tok1v);
  640.     strcat(newtok, tok2v);
  641.  
  642. #ifdef DEBUG
  643.     if (trcopt) {
  644.         fprintf(errfile, "Trying to merge <%s> and <%s> into <%s>\n",
  645.           tok1v, tok2v, newtok);
  646.         fprintf(errfile, "The new symbol %s in the symbol table\n",
  647.           (name_map(newtok)?"IS":"IS NOT") );
  648.     }
  649. #endif
  650.     if (name_map(newtok))
  651.         new_tok_sym = namemap(newtok, strlen(newtok));
  652.     else
  653.         new_tok_sym = EOFT_SYM;
  654.  
  655.     if (new_tok_sym < EOFT_SYM ) {
  656.  
  657.         TOKSYMS[++n_TOKSYMS] = new_tok_sym;
  658.  
  659.         u = prs_check(sta_stack, TOKSYMS, n_TOKSYMS) - BACKUPTOKS;
  660. #ifdef DEBUG
  661.         if (trcopt)
  662.             fprintf(errfile, " PRS_CHECK returns %d\n", u);
  663. #endif
  664.  
  665.         if (u > MAX_CHECK) {
  666.             candidate = CANDALLOC();
  667.             candidate->token_sym = new_tok_sym;
  668.             candidate->backup_toks = BACKUPTOKS;
  669.             candidate->next = (struct cand *)0;
  670.             MAX_CHECK = u;
  671.             cand_clear();
  672.             CANDIDATES[MERGE] = candidate;
  673.             n_CANDIDATES [MERGE] = 1;
  674.         }
  675.         else if (u == MAX_CHECK ) {
  676.             candidate = CANDALLOC();
  677.             candidate->token_sym = new_tok_sym;
  678.             candidate->backup_toks = BACKUPTOKS;
  679.             candidate->next = CANDIDATES[MERGE];
  680.             CANDIDATES[MERGE] = candidate;
  681.             n_CANDIDATES [MERGE] ++;
  682.         }
  683.  
  684.         j = TOKSYMS[n_TOKSYMS--]; /* dummy j */
  685.     }
  686.  
  687.     TOKSYMS[++n_TOKSYMS]  = nt;
  688.     TOKSYMS[++n_TOKSYMS]  = ct;
  689. }
  690.  
  691. void try_substitution()                                /*;try_substitution*/
  692. {
  693.     int    u;
  694.     short    ct;
  695.     struct two_pool *tmp_tp;
  696.     struct cand *candidate;
  697.  
  698. #ifdef DEBUG
  699.     if (trcopt)
  700.         fprintf(errfile, "try_substitution called\n");
  701. #endif
  702.  
  703.     if (TOKSYMS[n_TOKSYMS]  >= EOFT_SYM) /* do not delete a nonterminal*/
  704.         return;
  705.  
  706.     ct = TOKSYMS[n_TOKSYMS];
  707.  
  708.     /* poss_substs = {}; */
  709.  
  710. #ifdef DEBUG
  711.     if (trcopt)
  712.         fprintf(errfile, "Poss_substs : ");
  713. #endif
  714.     /*(for t in POSS_TOK)    */
  715.     tmp_tp = POSS_TOK;
  716.     while (tmp_tp != (struct two_pool *)0) {
  717.         TOKSYMS[n_TOKSYMS] = tmp_tp->val.state;
  718.         u = prs_check(sta_stack, TOKSYMS, n_TOKSYMS) - (BACKUPTOKS + 1);
  719.  
  720. #ifdef DEBUG
  721.         if (trcopt)
  722.             fprintf(errfile, " [ %s, %d ] ",
  723.               namelist((int)(tmp_tp->val.state)), u);
  724. #endif
  725.         if (u > MAX_CHECK ) {
  726.             candidate = CANDALLOC();
  727.             candidate->token_sym = tmp_tp->val.state;
  728.             candidate->backup_toks = BACKUPTOKS;
  729.             candidate->t3 = ct;
  730.             candidate->next = (struct cand *)0;
  731.             MAX_CHECK = u;
  732.             cand_clear();
  733.             CANDIDATES[SUBST] = candidate;
  734.             n_CANDIDATES[SUBST] = 1    ;
  735.         }
  736.         else if (u == MAX_CHECK ) {
  737.             candidate = CANDALLOC();
  738.             candidate->token_sym = tmp_tp->val.state;
  739.             candidate->backup_toks = BACKUPTOKS;
  740.             candidate->t3 = ct;
  741.             candidate->next = CANDIDATES[SUBST];
  742.             CANDIDATES[SUBST] = candidate;
  743.             n_CANDIDATES [SUBST] ++;
  744.         }
  745.         tmp_tp = tmp_tp->link;
  746.     }
  747. #ifdef DEBUG
  748.     if (trcopt)
  749.         fprintf(errfile, "\n");
  750. #endif
  751.  
  752.     TOKSYMS[n_TOKSYMS] = ct;
  753. }
  754.  
  755.